package taskTracker;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import taskTracker.util.Serializable;

/**
 * Holds a time entry logged by user.
 * @author aseldawy
 *
 */
public class TimeEntry implements Serializable {
	/**Start time of this time entry*/
	private long from;
	/**End time of this time entry*/
	private long to;
	/**Task associated with this time entry*/
	private Task task;
	/**Optional comment to this time entry*/
	private String comment;
	
	private static int MIN_SEPARATING_TIME_SPAN = - 3 * 60; // 3 minutes
	
	/**
	 * Creates a new time entry from the given fields
	 * @param from
	 * @param to
	 * @param task
	 * @param comment
	 */
	public TimeEntry(long from, long to, Task task, String comment) {
		super();
		this.from = from;
		this.to = to;
		this.task = task;
		this.comment = comment;
	}
	
	public long getTotalTime() {
		return this.to - this.from;
	}

	public long getFrom() {
		return from;
	}

	public void setFrom(long from) {
		this.from = from;
	}

	public long getTo() {
		return to;
	}

	public void setTo(long to) {
		this.to = to;
	}

	public Task getTask() {
		return task;
	}

	public void setTask(Task task) {
		this.task = task;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public TimeEntry(DataInputStream dis) {
		try
		{
			from = dis.readLong();
			to = dis.readLong();
			comment = dis.readUTF();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

	public void serialize(DataOutputStream dos) {
		try {
			dos.writeLong(from);
			dos.writeLong(to);
			dos.writeUTF(comment);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

	/**
	 * Determines whether the given TimeSpan intersects this time entry 
	 * But allow for a small margin determined by MIN_SEPARATING_TIME_SPAN
	 * that if the difference between the two spans is less than the value of
	 * MIN_SEPARATING_TIME_SPAN, then they're considered intersected.
	 *  
	 * @param spanFrom
	 * @param spanTo
	 * @return
	 */
	public boolean instersectTimeSpan(long spanFrom, long spanTo) {
		if(spanFrom <= this.from 
				&& spanTo - this.from > MIN_SEPARATING_TIME_SPAN){
			return true;
		}
		if(spanFrom >= this.from
				&& this.to - spanFrom > MIN_SEPARATING_TIME_SPAN){
			return true;
		}
		return false;
	}

	/**
	 * Returns the duration in millis of the intersection between this time entry and
	 * the given period.
	 * If there is no intersection, a -ve value is returned.
	 * @param spanFrom
	 * @param spanTo
	 * @return
	 */
	public long getIntersectedTimeSpan(long spanFrom, long spanTo){
		long intersectedFrom = Math.max(from, spanFrom);
		long intersectedTo = Math.min(to, spanTo);

		return intersectedTo - intersectedFrom;
	}

	public void mergeTimeSpan(long spanFrom, long spanTo) {
		from = Math.min(spanFrom, this.from);
		to = Math.max(spanTo, this.to);
	}
	
}
